package com.gzwh.v1.sysapi.conntroller.member;

import com.gzwh.v1.sysapi.core.LoginEnum;
import com.gzwh.v1.sysapi.core.jwt.AccessToken;
import com.gzwh.v1.sysapi.core.jwt.JwtConfig;
import com.gzwh.v1.sysapi.core.jwt.JwtUtil;
import com.gzwh.v1.sysapi.entity.UserBean;
import com.gzwh.v1.sysapi.entity.member.SFMemberEntity;
import com.gzwh.v1.sysapi.entity.valid.ValidMember;
import com.gzwh.v1.sysapi.server.member.MemberServer;
import com.gzwh.v1.sysapi.server.member.impl.MemberServerImpl;
import com.gzwh.v1.sysapi.shiro.CustomerAuthenticationToken;
import com.gzwh.v1.sysapi.utils.*;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import tk.mybatis.mapper.entity.Example;
import org.apache.shiro.authc.AuthenticationException;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

@CrossOrigin(maxAge = 36000)

/**
 * 后台管理入口，接口参数
 *
 * 其中涉及到登录、注册、注销登录
 *
 * 时间：2019-07-13
 */
@RestController
@RequestMapping("/api/member")
public class MenberController {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    MemberServerImpl memberServer;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private JwtConfig jwtConfig;
    @Autowired
    private StringRedisTemplate stringRedisTemplate = null;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelMap doLogin(@Valid ValidMember validMember, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
            return ReturnUtil.Error("用户名或密码为空", null, null);
        }
        String username = validMember.getUsername();
        CustomerAuthenticationToken token = new CustomerAuthenticationToken(validMember.getUsername(), validMember.getPassword(), false);
        token.setLoginType(LoginEnum.CUSTOMER.toString());
        //获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            logger.info("对用户[" + username + "]进行登录验证..验证开始");
            currentUser.login(token);
            logger.info("对用户[" + username + "]进行登录验证..验证通过");
        } catch (UnknownAccountException uae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
            redirectAttributes.addFlashAttribute("message", "未知账户");
        } catch (IncorrectCredentialsException ice) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
            redirectAttributes.addFlashAttribute("message", "密码不正确");
        } catch (LockedAccountException lae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "账户已锁定");
        } catch (ExcessiveAttemptsException eae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");
        } catch (AuthenticationException ae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
//            ae.printStackTrace();
            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
        }
        //验证是否登录成功
        if (currentUser.isAuthenticated()) {
//            Session session = currentUser.getSession();
//            session.setAttribute("loginType", LoginEnum.CUSTOMER.toString());
//            logger.info("前台用户[" + username + "]登录认证通过");
//            return ReturnUtil.Success("登录成功");

//            Session session = SecurityUtils.getSubject().getSession();
//            session.setAttribute("loginType", LoginEnum.CUSTOMER.toString());
//            String sessionId = session.getId().toString();
            SFMemberEntity sfMemberEntity = (SFMemberEntity) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
//            String accessToken = jwtUtil.createJWT(username, jwtConfig.getSecret(),LoginEnum.CUSTOMER.toString(),validMember.getPassword());

            String accessToken=JWTUtil.sign(username,jwtConfig.getSecret(),LoginEnum.CUSTOMER.toString(),validMember.getPassword());
            stringRedisTemplate.opsForValue().set("type:member:" + accessToken, "type:member:" + accessToken,2, TimeUnit.HOURS);

//            String accessToken = JWTUtil.sign(username, "123123");
            //返回accessToken
            AccessToken accessTokenEntity = new AccessToken();
            accessTokenEntity.setAccessToken(accessToken);
            accessTokenEntity.setExpiresIn(jwtConfig.getExpiration());
            accessTokenEntity.setTokenType(jwtConfig.getTokenHead());
            return ReturnUtil.Success("登录成功", accessTokenEntity);
        } else {
            token.clear();
            return ReturnUtil.Error((String) redirectAttributes.getFlashAttributes().get("message"), null, null);
        }
    }


    /**
     * 处理注册操作
     *
     * @param sfMemberEntity
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/reg", method = RequestMethod.POST)
    public ModelMap doReg(@Valid SFMemberEntity sfMemberEntity, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnUtil.Error("请填写必填参数", null, null);
        }
        try {
            Example example = new Example(SFMemberEntity.class);
            example.createCriteria().andCondition("name = ", sfMemberEntity.getName());
            Integer userCount = memberServer.getCount(example);
            if (userCount > 0) {
                return ReturnUtil.Error("用户名已存在", null, null);
            }
            example.clear();
            example.createCriteria().andCondition("mail = ", sfMemberEntity.getMail());
            Integer mailCount = memberServer.getCount(example);
            if (mailCount > 0) {
                return ReturnUtil.Error("该邮箱已存在", null, null);
            }

            String Id = UuidUtil.getUUID();
            sfMemberEntity.setUuid(Id);
            String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
//            userBean.setSalt(salt);
            String password = PasswordUtil.createCustomPwd(sfMemberEntity.getPassword(), "123");
            sfMemberEntity.setPassword(password);
            sfMemberEntity.setIsLock(0);
            sfMemberEntity.setRegTime(DateUtil.getCurrentTime());
            DateUtil dateUtil = new DateUtil();
            sfMemberEntity.setEndTime(dateUtil.getStrDate("360"));
            memberServer.insertSFMember(sfMemberEntity);
            return ReturnUtil.Success("操作成功", null, null);
        } catch (Exception e) {
            e.printStackTrace();
            return ReturnUtil.Error("操作失败", null, null);
        }
    }

    @RequestMapping(value = "/info", method = RequestMethod.GET)
    @RequiresAuthentication
    public ModelMap doReg() {
        return ReturnUtil.Success("操作成功", null, null);
    }


    /**
     * 退出
     *
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public ModelMap logout(@RequestHeader("Authorization") String Authorization) {
        System.out.println("MemberController.logout()");
        try {
            stringRedisTemplate.delete("type:member:" + Authorization);
            SecurityUtils.getSubject().logout();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return ReturnUtil.Success("您已安全退出", null, null);

    }
}
